

/**
  ******************************************************************************
  * @file    kea8_pwm.c
  * @author  花溪村长
  * @version V1.0
  * @date    4-11-2015
  * @brief   This file contains all the functions prototypes for the FTM 
  *          firmware library.
  ******************************************************************************
  * @attention  参考于苏州大学KEA128底层驱动库
  *
  ******************************************************************************
  */
	
#include "kea128_ftm.h"


static uint16_t MOD_VALUE;
/**
  * @brief  FTM_PWM_init
  * @param  CHANNELx: Select the CHANNEL0 or the CHANNEL6 peripheral. 
  * @param  duty 占空比
  * @param  FTMx FTM模块
	* @param freq：设置PWM的频率，单位为KHz。取值从0.012到1500
	* @param duty：占空比：精度取决于设置的freq值，精度为freq/1500。
  * @retval None
  */
	
void FTM_PWM_Init(FTM_Type * FTMx,FTM_InitTypeDef *FTM_InitStruct)
{
	uint16_t duty_channel;
	uint16_t mod;
	uint16_t ftm;
	ASSERT(IS_CHANNEL(FTM_InitStruct->CHANNEL));
	ASSERT(IS_FTM(FTMx));
	if(FTMx == FTM0)
  ftm = FTM_0;
	else if(FTMx == FTM1)
		ftm=FTM_1 ;
	else ftm=FTM_2 ;
	//计算mod值，周期（ms) = MOD / 1500
	if(FTM_InitStruct->Frequency <= 0.012)
		mod = 0xFFFF;
	else if(FTM_InitStruct->Frequency>1500)
		mod=0;
	else
		mod = 1500 / FTM_InitStruct->Frequency;

	//防止周期越界
	if(FTM_InitStruct->Duty > 100)
		FTM_InitStruct->Duty = 100;
	if(FTM_InitStruct->Duty < 0)
		FTM_InitStruct->Duty = 0;
  
	switch(ftm)
	{
		case FTM_0:
		{
			  if(FTM_InitStruct->PIN == 0)
			{
				SIM_PINSEL0 &= FTM_InitStruct->PIN ; 
			}else SIM_PINSEL0 &= ~FTM_InitStruct->PIN ;
			SIM_PINSEL0 |= SIM_PINSEL0 &= FTM_InitStruct->PIN ;
				//使能FTM0的总线时钟
			 SIM_SCGC |= SIM_SCGC_FTM0_MASK;
			 break;
		}
		case FTM_1:
		{
			if(FTM_InitStruct->PIN == 0)
			{
				SIM_PINSEL0 &= FTM_InitStruct->PIN ; 
			}else SIM_PINSEL0 &= ~FTM_InitStruct->PIN ;
			SIM_PINSEL0 |= SIM_PINSEL0 &= FTM_InitStruct->PIN ; 
			//使能FTM1的总线时钟
			SIM_SCGC |= SIM_SCGC_FTM1_MASK;
			break;
		}
		case FTM_2:
		{
		  SIM_PINSEL1 = FTM_InitStruct->PIN;
			//使能FTM2的总线时钟
			SIM_SCGC |= SIM_SCGC_FTM2_MASK;
			break;
	 }
  }
    //写保护禁止
    FTMx->MODE |= FTM_MODE_WPDIS_MASK;
    //总线时钟频率20MHz,分频因子16,分频后为1.25MHz
    FTMx->SC |= FTM_SC_PS(4);
    //左对齐，先高电平后低电平
    FTM_CnSC_REG(FTMx, FTM_InitStruct->CHANNEL) |= FTM_CnSC_ELSB_MASK;
    //边沿对齐
    FTM_CnSC_REG(FTMx, FTM_InitStruct->CHANNEL) &= ~FTM_CnSC_ELSA_MASK;
    FTM_CnSC_REG(FTMx, FTM_InitStruct->CHANNEL) |= FTM_CnSC_MSB_MASK;
    //计数器清零
    FTMx->CNT=0;
    //中断禁止
    FTMx->SC &=  ~FTM_SC_TOIE_MASK;
    //FTM2使能
    FTMx->MODE &= ~FTM_MODE_FTMEN_MASK;
    //启用需要的输出通道，屏蔽其他通道
    FTMx->OUTMASK = (0xFE << FTM_InitStruct->CHANNEL);
    //禁止双边沿捕捉模式
    FTMx->COMBINE = 0;
    //FTM2计数初始值为0
    FTMx->CNTIN = 0;
    //周期=(MOD-CNTIN+1)*时钟周期=2.5ms
    FTMx->MOD = mod;
    MOD_VALUE = mod;
    //计算通道寄存器的值，设置占空比
    duty_channel = (uint16_t)((float)mod * FTM_InitStruct->Duty / 100);
    //设置通道值寄存器
    FTM_CnV_REG(FTMx, FTM_InitStruct->CHANNEL) = duty_channel;
    //使用总线时钟
    FTMx->SC |= FTM_SC_CLKS(1);	
}


/**
  * @brief  FTM_PWM_set_duty
  * @param  CHANNELx: Select the CHANNEL0 or the CHANNEL6 peripheral. 
  * @param  duty 占空比
  * @param  FTMx FTM模块
  * @retval None
  */
void FTM_PWM_set_duty(FTM_Type *FTMx, uint8_t channel, float duty)
{
	uint16_t duty_channel;

	if(duty > 100)
		duty = 100;
	if(duty < 0)
		duty = 0;
    //写保护禁止
    // FTM_ARR[ftmNo]->MODE |= FTM_MODE_WPDIS_MASK;
    //计算通道寄存器的值，设置占空比
    duty_channel = (uint16_t)((float)MOD_VALUE * duty / 100);
    //设置通道值寄存器
    FTM_CnV_REG(FTMx, channel) = duty_channel;
}

